using Cysharp.Threading.Tasks;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GameAOT;
using IQIGame.Rendering;
using System;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class UIStorySystem : UIEntityWindow
    {
        /// <summary>
        /// 静态配置
        /// </summary>
        private static UICreateConfig _createConfig = new()
        {
            prefabName = nameof(UIStorySystem),
            layer = EUILayer.Middle,
        };

        /// <summary>
        /// 创建UI的配置
        /// </summary>
        public override IUICreateConfig createConfig => _createConfig;

        #region Template Generate,don't modify
        protected partial class UIB_UIStorySystem
        {
            #region ObjectBinding Generate
            public GameObject textPanel { protected set; get; }
            public IQIGame.Onigao.Framework.ExText tex_SpeakName { protected set; get; }
            public IQIGame.Onigao.Framework.ExText tex_Content { protected set; get; }
            public IQIGame.Onigao.GamePlay.ExButtonStory btn_bg { protected set; get; }
            public DG.Tweening.DOTweenAnimation dt_Content { protected set; get; }
            public GameObject optionItem { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btn_Skip { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btn_Review { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btn_AutoPlay { protected set; get; }
            public IQIGame.Onigao.Framework.ExRawImage img_bg { protected set; get; }
            protected virtual void InitBinding(ObjectBinding __binding)
            {
                var __tbv0 = __binding.GetVariableByName("textPanel");
                this.textPanel = __tbv0.GetValue<GameObject>();
                var __tbv1 = __binding.GetVariableByName("tex_SpeakName");
                this.tex_SpeakName = __tbv1.GetValue<IQIGame.Onigao.Framework.ExText>();
                var __tbv2 = __binding.GetVariableByName("tex_Content");
                this.tex_Content = __tbv2.GetValue<IQIGame.Onigao.Framework.ExText>();
                var __tbv3 = __binding.GetVariableByName("btn_bg");
                this.btn_bg = __tbv3.GetValue<IQIGame.Onigao.GamePlay.ExButtonStory>();
                var __tbv4 = __binding.GetVariableByName("dt_Content");
                this.dt_Content = __tbv4.GetValue<DG.Tweening.DOTweenAnimation>();
                var __tbv5 = __binding.GetVariableByName("optionItem");
                this.optionItem = __tbv5.GetValue<GameObject>();
                var __tbv6 = __binding.GetVariableByName("btn_Skip");
                this.btn_Skip = __tbv6.GetValue<IQIGame.Onigao.Framework.ExButton>();
                var __tbv7 = __binding.GetVariableByName("btn_Review");
                this.btn_Review = __tbv7.GetValue<IQIGame.Onigao.Framework.ExButton>();
                var __tbv8 = __binding.GetVariableByName("btn_AutoPlay");
                this.btn_AutoPlay = __tbv8.GetValue<IQIGame.Onigao.Framework.ExButton>();
                var __tbv9 = __binding.GetVariableByName("img_bg");
                this.img_bg = __tbv9.GetValue<IQIGame.Onigao.Framework.ExRawImage>();
            }
            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify

        /// <summary>
        /// 可以自定义修改的
        /// </summary>
        protected partial class UIB_UIStorySystem
        {
            public virtual void StartBinding(GameObject __go)
            {
                var binding = __go.GetComponent<ObjectBinding>();
                if (binding != null)
                {
                    this.InitBinding(binding);
                }
            }
        }
        protected UIB_UIStorySystem ui { get; set; }

        #region Variable
        // 选项item池子
        private UIItemPool<UIN_StoryOptionItem> poolOptionItems;
        // event
        private Action<int> _chooseOpetionEvent;
        // 当前配置
        private CfgStory.CfgStoryShow _cfgStoryFragment;
        // 播放的上下文数据
        private StoryPlayContext _storyContext;
        // 当前一幕是否完成
        private AutoResetUniTaskCompletionSource<eStoryNextState> _completeActTaskSource;
        // 文字Tween是否完成
        private bool _tweenTextContentPlaying;
        // 当前时候有选项
        private bool _hasChooseOption;
        // 当前选择的选项Index
        private int _currentSelectIndex;

        // 上次背景图片类型
        private CfgStory.StoryBackGroundType _lastBackGroundType;
        private RenderTexture _blackGroundRT;
        const string _blackGroundRTName = "UIStoryBackGround";
        private ResLoader _bgResloader;

        #endregion

        protected override void BeforeInit()
        {
            ui = new UIB_UIStorySystem();
            ui.StartBinding(gameObject);
        }

        protected override void OnInit()
        {
            poolOptionItems = this.InitPool<UIN_StoryOptionItem>(this.ui.optionItem);
            this.ui.btn_bg.onClick.AddListener(OnBackGroudClick);
            this.ui.dt_Content.onComplete.AddListener(TweenTextConetentComplete);
            this.ui.btn_Skip.AddClickEvent(OnBtnSkipStory);
            _chooseOpetionEvent = this.OnChoseOptionItemClicked;
            _bgResloader = ResLoader.Create();
        }

        protected override void OnShow(UIBaseData data)
        {

        }

        protected override void OnHide()
        {

        }

        protected override void OnDispose()
        {
            if (_completeActTaskSource != null)
            {
                _completeActTaskSource = null;
                var rTcs = _completeActTaskSource;
                rTcs.TrySetCanceled();
            }
            if (_bgResloader != null)
            {
                _bgResloader.Put2Pool();
                _bgResloader = null;
            }

            RenderBlurUtil.ReleaseBlurRT(_blackGroundRTName);
            _blackGroundRT = null;
        }

        /// <summary>
        /// 播放一幕剧情
        /// </summary>
        public async UniTask PlayStoryAct(StoryPlayContext storyPlayContext)
        {
            if (_completeActTaskSource != null)
            {
                LogGame.LogError($"上一幕剧情还未播放完毕，不能播放下一幕剧情");
            }

            this._storyContext = storyPlayContext;

            if (!storyPlayContext.EnterCurrentStoryFragmentCfg(out _cfgStoryFragment))
            {
                if (!storyPlayContext.isSendedEndService)
                {
                    // 校验是否正常结束
                    LogGame.LogError($"Story[{this._storyContext.storyName}]配置错误，没有结束的配置");
                }
                //结束
                return;
            }

            //创建等待任务
            _completeActTaskSource = AutoResetUniTaskCompletionSource<eStoryNextState>.Create();

            // 开始播放显示
            this.RefreshStoryShow();

            // 等待完成
            var nextState = await _completeActTaskSource.Task;

            // 检测是否有服务要发送
            if (_storyContext.CheckerStoryService() || nextState == eStoryNextState.SkipStory)
            {
                await _storyContext.SendStoryService();
            }

            // 根据下个状态指示器，做响应的处理
            switch (nextState)
            {
                case eStoryNextState.None:
                    break;

                case eStoryNextState.ContinueNextAct:

                    if (_cfgStoryFragment.JumpID.Count == 0)
                    {
                        // 直接进入下一行
                        await PlayStoryAct(storyPlayContext.NextIndex());
                    }
                    else
                    {
                        // 跳转的情况
                        int nextIndex = -1;
                        if (_hasChooseOption)
                        {
                            // 选项跳转
                            var jumpId = _cfgStoryFragment.JumpID[this._currentSelectIndex];
                            nextIndex = storyPlayContext.GetNewIndexByJumpId(jumpId);
                        }
                        else
                        {
                            // 无条件跳转
                            var jumpId = _cfgStoryFragment.JumpID[0];
                            nextIndex = storyPlayContext.GetNewIndexByJumpId(jumpId);
                        }

                        // 跳转到某一行索引的配置
                        await PlayStoryAct(storyPlayContext.JumpToIndex(nextIndex));
                    }
                    break;

                case eStoryNextState.SkipStory:
                    // 跳过并且结束
                    await PlayStoryAct(storyPlayContext);
                    break;
            }
        }

        private void CallActTaskComplete(eStoryNextState nextState)
        {
            if (_completeActTaskSource != null)
            {
                // 注意！这里要先置空，再调用，TrySetResult会先调用await之后的代码，如果await之后有给TaskSource赋新值，然后这里再置空，那么_completeActTaskSource就永远为null了。
                // 若置空不及时导致了多次source.TrySetResult，会导致池内数据异常
                var ts = _completeActTaskSource;
                _completeActTaskSource = null;
                ts.TrySetResult(nextState);
            }

        }

        /// <summary>
        /// 刷新当前的这一幕的剧情显示
        /// </summary>
        private void RefreshStoryShow()
        {
            // 背景
            ShowBackground().Forget();

            // 文字
            ShowTextContent();

            // 选项
            ShowChooseOption();

        }

        private void ShowTextContent()
        {
            // 文字
            this.ui.tex_SpeakName.text = _cfgStoryFragment.Speaker;
            this.ui.tex_Content.text = "";
            (this.ui.dt_Content.tween as TweenerCore<string, string, StringOptions>)?.ChangeEndValue(_cfgStoryFragment.Contents, 10, false);
            this.ui.dt_Content.DORestart();
            _tweenTextContentPlaying = true;
        }

        private async UniTaskVoid ShowBackground()
        {
            //背景
            switch (_cfgStoryFragment.BackgroundType)
            {
                case CfgStory.StoryBackGroundType.Delete:
                    ClearBackGround();
                    this.ui.img_bg.gameObject.SetActive(false);
                    break;
                case CfgStory.StoryBackGroundType.BlurGenerate:
                    if (_cfgStoryFragment.BackgroundType != _lastBackGroundType)
                    {
                        ClearBackGround();
                    }
                    else
                    {
                        break;
                    }

                    _blackGroundRT = await RenderBlurUtil.GetBlurTexAsyncReadBack(_blackGroundRTName, GameRender.CameraType.MainCamera);
                    if (_blackGroundRT != null)
                    {
                        this.ui.img_bg.texture = _blackGroundRT;
                        this.ui.img_bg.gameObject.SetActive(true);
                    }
                    break;
                case CfgStory.StoryBackGroundType.Asset:
                    ClearBackGround();
                    //_bgResloader.LoadAsync(_cfgStoryFragment.BackgroundAssetPath, (obj) =>
                    //{
                    //    this.ui.img_bg.texture = obj as Texture;
                    //});
                    break;
                default:
                    // 保持不变
                    break;
            }

            _lastBackGroundType = _cfgStoryFragment.BackgroundType;
        }

        private void ClearBackGround()
        {
            this.ui.img_bg.texture = null;
            _bgResloader.ReleaseAllRes();

            RenderBlurUtil.ReleaseBlurRT(_blackGroundRTName);
            _blackGroundRT = null;
            _lastBackGroundType = CfgStory.StoryBackGroundType.None;
        }

        /// <summary>
        /// 选项
        /// </summary>
        private void ShowChooseOption()
        {
            this.poolOptionItems.HideAll();
            _hasChooseOption = false;
            if (_cfgStoryFragment.NextDialogName.Count == 0)
            {
                return;
            }
            if (_cfgStoryFragment.NextDialogName.Count != _cfgStoryFragment.JumpID.Count)
            {
                LogGame.LogError($"Story[{this._storyContext.storyName}]配置错误，NextDialogName和JumpID数量不一致");
                return;
            }
            _hasChooseOption = true;
            _currentSelectIndex = -1;
            for (int i = 0; i < _cfgStoryFragment.NextDialogName.Count; i++)
            {
                if (_cfgStoryFragment.ChooseCondition.Count > 0)
                {
                    if (_cfgStoryFragment.ChooseCondition.Count != _cfgStoryFragment.NextDialogName.Count)
                    {
                        LogGame.LogError($"对话选项条件数量和选项数量不匹配，选项数量：{_cfgStoryFragment.NextDialogName.Count}, 条件数量：{_cfgStoryFragment.ChooseCondition.Count}");
                        return;
                    }
                    int conditionId = _cfgStoryFragment.ChooseCondition[i];
                    (bool isOK, int failId) = GameplayAreaManager.Instance.curSceneArea.CheckCondition(conditionId, null);
                    if (!isOK)
                    {
                        continue;
                    }
                }
                var optionContent = _cfgStoryFragment.NextDialogName[i];
                var item = this.poolOptionItems.GetOne();
                item.InitOptionItem(i, optionContent, _chooseOpetionEvent);
            }

        }

        private void TweenTextConetentComplete()
        {
            _tweenTextContentPlaying = false;
        }

        #region UI Event 

        // 点击背景的时候
        public void OnBackGroudClick()
        {
            if (_tweenTextContentPlaying)
            {
                this.ui.dt_Content.DOComplete();
                return;
            }

            if (_hasChooseOption)
            {
                return;
            }

            CallActTaskComplete(eStoryNextState.ContinueNextAct);
        }

        /// <summary>
        /// 选项点击的时候
        /// </summary>
        /// <param name="index"></param>
        public void OnChoseOptionItemClicked(int index)
        {
            _currentSelectIndex = index;

            // 缓存历史选项
            _storyContext.SaveChoiceOption(this._cfgStoryFragment.Id, _currentSelectIndex);

            // next
            CallActTaskComplete(eStoryNextState.ContinueNextAct);
        }


        public void OnBtnSkipStory()
        {
            int nextIndex = _storyContext.SkipStory();
            if (nextIndex == _storyContext.currentIndex)
            {
                // 当前无法跳过
                return;
            }
            _storyContext.JumpToIndex(nextIndex);

            CallActTaskComplete(eStoryNextState.SkipStory);
        }
        #endregion

    }
}
